/**
 * 
 */
package data;

import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;

import data.Data.TeamID;
import engine.Pitch;

/**
 * @author bogdan
 * 
 */
public class Position implements Serializable {
	private static final long serialVersionUID = 7587879714092119711L;
	private int m_x;
	private int m_y;

	/**
	 * Default constructor. Initialises a position at (0, 0)
	 */
	public Position() {
		m_x = 0;
		m_y = 0;
	}

	/**
	 * Constructor.
	 * 
	 * @param x
	 *            - the position on the x axis
	 * @param y
	 *            - the position on the y axis
	 */
	public Position(final int x, final int y) {
		m_x = x;
		m_y = y;
	}

	/**
	 * Constructor
	 * 
	 * @param other
	 *            - the position
	 */
	public Position(final Position pos) {
		setPosition(pos);
	}

	public int distance(final Position other) {
		// double dist = Math.sqrt((m_x - other.m_x) * (m_x - other.m_x) + (m_y
		// - other.m_y) * (m_y - other.m_y));
		// return (int) Math.floor(dist);
		// return Math.abs(m_x - other.m_x) + Math.abs(m_y - other.m_y);
		return Math.max(Math.abs(m_x - other.m_x), Math.abs(m_y - other.m_y));
	}

	public int distance(final Collection<Position> others) {
		int min = Integer.MAX_VALUE;
		final Iterator<Position> it = others.iterator();
		while (it.hasNext()) {
			final Position position = it.next();
			final int distance = position.distance(this);
			if (distance < min) {
				min = distance;
			}
		}
		return min;
	}

	public double distanceAlt(final Position other) {
		return Math.sqrt((m_x - other.m_x) * (m_x - other.m_x) + (m_y - other.m_y) * (m_y - other.m_y));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		final Position other = (Position) obj;
		if (m_x != other.m_x) {
			return false;
		}
		if (m_y != other.m_y) {
			return false;
		}
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + m_x;
		result = prime * result + m_y;
		return result;
	}

	/**
	 * Checks if an other position is a neighbour of this position.
	 * 
	 * @param pos
	 *            other position
	 * @return is a neighbour
	 * 
	 * @author Tomasz Dąbrowski
	 */
	public boolean isNeighbour(final Position pos) {
		return Math.abs(m_x - pos.x()) <= 1 && Math.abs(m_y - pos.y()) <= 1;
	}

	/**
	 * Sets the position.
	 * 
	 * @param pos
	 *            - the new position.
	 */
	public void setPosition(final Position pos) {
		m_x = pos.x();
		m_y = pos.y();
	}

	// getters and setters
	public void setX(final int x) {
		m_x = x;
	}

	public void setY(final int y) {
		m_y = y;
	}

	@Override
	public String toString() {
		return "(" + m_x + ", " + m_y + ")";
	}

	public int x() {
		return m_x;
	}

	public int y() {
		return m_y;
	}

	public int distanceToEndZone(final TeamID teamId) {
		switch (teamId) {
		case TEAM_A:
			return m_x - (Pitch.PITCH_WIDTH - 1);
		case TEAM_B:
			return m_x;
		default:
			return -1;
		}
	}

}
